package config;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.StringTokenizer;

import data.Logger;

import environment.*;

public class ConfigReader 
{
	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void readSettings(String filename) throws Exception 
	{
		/** TESTING ConfigReader class **/
		FileReader fr = new FileReader(filename);
		BufferedReader br = new BufferedReader(fr);
		String s;
		while ((s = br.readLine()) != null) 
		{
			if(s.startsWith("goal"))
				readGoalValues(s);
			if(s.startsWith("screen"))
				readScreenValues(s);
			if(s.startsWith("weights"))
				readWeightValues(s);
		}
		fr.close();
	}
	
	public static void readObjects(String filename) throws Exception 
	{
		/** TESTING ConfigReader class **/
		FileReader fr = new FileReader(filename);
		BufferedReader br = new BufferedReader(fr);
		String s;
		while ((s = br.readLine()) != null) 
		{
			if(s.startsWith("robot"))
				readRobotValues(s);
			if(s.startsWith("obstacle"))
				readObstacleValues(s);
			if(s.startsWith("box"))
				readBoxValues(s);
		}
		fr.close();
	}
	
	public static void readScreenValues(String s)
	{
		StringTokenizer st = new StringTokenizer(s);
		int w = ScreenConstants.DEFAULT_SCREEN_WIDTH, 
			h = ScreenConstants.DEFAULT_SCREEN_HEIGHT,
			n = 1, msDelay =-1;
		
		double partialFailChance = 0.5;
		
		// for Color
		int colorR = 0, colorG = 0, colorB = 0;
		boolean changeColor = false;
		
		while(st.hasMoreTokens())
		{
			String token = st.nextToken();
			if(token.startsWith("w="))
				w = new Integer(token.substring(2));
			if(token.startsWith("h="))
				h = new Integer(token.substring(2));
			if(token.startsWith("runs="))
				n = new Integer(token.substring(5));
			if(token.startsWith("colorR="))
			{
				colorR = new Integer(token.substring(7));
				changeColor = true;
			}
			if(token.startsWith("colorG="))
			{
				colorG = new Integer(token.substring(7));
				changeColor = true;
			}
			if(token.startsWith("colorB="))
			{
				colorB = new Integer(token.substring(7));
				changeColor = true;
			}
			if(token.startsWith("delay="))
				msDelay = new Integer(token.substring(6));
			if(token.startsWith("partialFailChance="))
			{
				partialFailChance = new Double(token.substring(18));
				Robot.partialFailChance = partialFailChance;
			}
			if(token.startsWith("DEBUG_MULTIPLE_ROBOTS_PUSHING"))
				Main.DEBUG_MULTIPLE_ROBOTS_PUSHING = true;
			if(token.startsWith("STOP_EXECUTION_WHEN_STUCK"))
				Main.STOP_EXECUTION_WHEN_STUCK = true;
			if(token.startsWith("RUN_FALSE_TOLERANCE_TESTS"))
				Main.RUN_FALSE_TOLERANCE_TESTS = true;
			if(token.startsWith("FT0"))
				Main.FT0 = true;
			if(token.startsWith("FT1"))
				Main.FT1 = true;
			if(token.startsWith("FT2"))
				Main.FT2 = true;
			if(token.startsWith("FT3"))
				Main.FT3 = true;
			if(token.startsWith("FT4"))
				Main.FT4 = true;
			if(token.startsWith("NO_ARTIFICIAL_IMMUNE"))
				Main.NO_ARTIFICIAL_IMMUNE = true;
			if(token.startsWith("SUCCESS_RATE_LEARNING"))
			{
				Main.SUCCESS_RATE_LEARNING = true;
				Main.LEARNING_RATE = new Integer(token.substring(22));
			}
		}
		ScreenConstants.setScreen(w, h);
		if(Main.numberOfRuns == -1)
		{
			Main.numberOfRuns = n;
		}
		if(Main.simulationDelay == -1)
		{
			Main.simulationDelay = msDelay;
		}
		if(changeColor) Main.stringColor = new Color(colorR,colorG,colorB);
	}
	
	public static void readWeightValues(String s)
	{
		StringTokenizer st = new StringTokenizer(s);
		int w1 = 0, w2 = 0, w3 = 0, w4 = 0;
		while(st.hasMoreTokens())
		{
			String token = st.nextToken();
			if(token.startsWith("w1="))
				w1 = new Integer(token.substring(3));
			if(token.startsWith("w2="))
				w2 = new Integer(token.substring(3));
			if(token.startsWith("w3="))
				w3 = new Integer(token.substring(3));
			if(token.startsWith("w4="))
				w4 = new Integer(token.substring(3));
		}
		
		RobotHelper.w1 = w1;
		RobotHelper.w2 = w2;
		RobotHelper.w3 = w3;
		RobotHelper.w4 = w4;
	}
	
	public static void readRobotValues(String s)
	{
		StringTokenizer st = new StringTokenizer(s);
		int x = 0, y = 0, w = 15, h = 15, v = 10, angle = 0;
		// color variables
		int colorR = 0, colorG = 0, colorB = 0, drawType = 0;
		boolean changeColor = false;
		/** failure probability: Pushing, Wandering , Helping **/
		float failP = 1, failW = 1, failH = 1;
		
		Robot r;
		Capabilities c = new Capabilities();
		
		while(st.hasMoreTokens())
		{
			String token = st.nextToken();
			if(token.startsWith("x="))
				x = new Integer(token.substring(2));
			if(token.startsWith("y="))
				y = new Integer(token.substring(2));
			if(token.startsWith("w="))
				w = new Integer(token.substring(2));
			if(token.startsWith("h="))
				h = new Integer(token.substring(2));
			if(token.startsWith("v="))
				v = new Integer(token.substring(2));
			if(token.startsWith("angle="))
				angle = new Integer(token.substring(6));
			if(token.startsWith("colorR="))
			{
				colorR = new Integer(token.substring(7));
				changeColor = true;
			}
			if(token.startsWith("colorG="))
			{
				colorG = new Integer(token.substring(7));
				changeColor = true;
			}
			if(token.startsWith("colorB="))
			{
				colorB = new Integer(token.substring(7));
				changeColor = true;
			}
			if(token.startsWith("failP="))
				failP = new Float("0." + token.substring(6));
			if(token.startsWith("failW="))
				failW = new Float("0." + token.substring(6));
			if(token.startsWith("failH="))
				failH = new Float("0." + token.substring(6));
			if(token.startsWith("failA="))
			{
				/** sets all failure probability **/
				failP = new Float("0." + token.substring(6));
				failW = failP;
				failH = failP;
			}
			if(token.startsWith("drawType="))
				drawType = new Integer(token.substring(9));
			if(token.startsWith("maxPayload"))
				c.setMaxPayload(true);
			if(token.startsWith("arm"))
				c.setArm(true);
			if(token.startsWith("mobility"))
				c.setMobility(true);
			if(token.startsWith("sensors"))
				c.setSensors(true);
			if(token.startsWith("gripper"))
				c.setGripper(true);
		}
		if(h > w)
		{
			int t = h;
			h = w;
			w = t;
		}
		Main.robotCount++;
		r = new Robot("r" + Main.robotCount, x, y, w, h, Main.g1);
		r.setCap(c);
		r.setFailureChance(failP, Robot.FailState.PUSH);
		r.setFailureChance(failW, Robot.FailState.WANDER);
		r.setFailureChance(failH, Robot.FailState.HELP);
		r.setVelocity(v);
		r.setAngle(angle);
		if(changeColor) r.setColor(new Color(colorR,colorG,colorB));
		r.drawType = drawType;
		Main.generateRobot(r);
	}
	
	public static void readObstacleValues(String s)
	{
		StringTokenizer st = new StringTokenizer(s);
		int x = 0, y = 0, r = 10;
		while(st.hasMoreTokens())
		{
			String token = st.nextToken();
			if(token.startsWith("x="))
				x = new Integer(token.substring(2));
			if(token.startsWith("y="))
				y = new Integer(token.substring(2));
			if(token.startsWith("r="))
				r = new Integer(token.substring(2));
		}
		Main.generateObstacle(x, y, r);
	}
	
	public static void readBoxValues(String s)
	{
		StringTokenizer st = new StringTokenizer(s);
		int x = 0, y = 0, w = 50, h = 100, n = 1, angle = 0;
		// color variables
		int colorR = 0, colorG = 0, colorB = 0;
		boolean changeColor = false;
		
		Capabilities c = new Capabilities();
		
		while(st.hasMoreTokens())
		{
			String token = st.nextToken();
			if(token.startsWith("x="))
				x = new Integer(token.substring(2));
			if(token.startsWith("y="))
				y = new Integer(token.substring(2));
			if(token.startsWith("w="))
				w = new Integer(token.substring(2));
			if(token.startsWith("h="))
				h = new Integer(token.substring(2));
			if(token.startsWith("n="))
				n = new Integer(token.substring(2));
			if(token.startsWith("angle="))
				angle = new Integer(token.substring(6));
			if(token.startsWith("colorR="))
			{
				colorR = new Integer(token.substring(7));
				if(colorR > 255) colorR = 255;
				changeColor = true;
			}
			if(token.startsWith("colorG="))
			{
				colorG = new Integer(token.substring(7));
				if(colorG > 255) colorG = 255;
				changeColor = true;
			}
			if(token.startsWith("colorB="))
			{
				colorB = new Integer(token.substring(7));
				if(colorB > 255) colorB = 255;
				changeColor = true;
			}
			if(token.startsWith("maxPayload"))
				c.setMaxPayload(true);
			if(token.startsWith("arm"))
				c.setArm(true);
			if(token.startsWith("mobility"))
				c.setMobility(true);
			if(token.startsWith("sensors"))
				c.setSensors(true);
			if(token.startsWith("gripper"))
				c.setGripper(true);
		}
		if(h > w)
		{
			int t = h;
			h = w;
			w = t;
		}
		if(changeColor)
		{
			Color color = new Color(colorR, colorG, colorB);
			Main.generateBox(x, y, w, h, angle, n, c, color);
			return;
		}
		else
			Main.generateBox(x, y, w, h, angle, n, c);
	}
	
	public static void readGoalValues(String s)
	{
		StringTokenizer st = new StringTokenizer(s);
		int x = 0, y = 0, r = 10;
		while(st.hasMoreTokens())
		{
			String token = st.nextToken();
			if(token.startsWith("x="))
				x = new Integer(token.substring(2));
			if(token.startsWith("y="))
				y = new Integer(token.substring(2));
			if(token.startsWith("r="))
				r = new Integer(token.substring(2));
		}
		Main.g1 = new Goal(x, y, r);
		Logger.log("** Goal is at: (" + x + ", " + y + ") with r: " + r);
	}
	
	public static void logSettings()
	{
		/** log weights **/
		Logger.log("\n** Weights (w1, w2, w3, w4, w5): (" + RobotHelper.w1 + ", " + RobotHelper.w2 + ", " +
				RobotHelper.w3 + ", " + RobotHelper.w4 + ", " + RobotHelper.w5 + ")");
		
		/** log flags **/
		Logger.log("\n** Flags **");
		Logger.log("** NO_ARTIFICIAL_IMMUNE - " + (Main.NO_ARTIFICIAL_IMMUNE? "ON" : "OFF"));
		Logger.log("** DEBUG_MULTIPLE_ROBOTS_PUSHING - " + (Main.DEBUG_MULTIPLE_ROBOTS_PUSHING? "ON" : "OFF"));
		Logger.log("** STOP_EXECUTION_WHEN_STUCK - " + (Main.STOP_EXECUTION_WHEN_STUCK? "ON" : "OFF"));
		
		/** log other settings **/
		Logger.log("\n** Settings **");
		Logger.log("** Runs - " + (Main.numberOfRuns < 0? "1" : "" + Main.numberOfRuns));
		Logger.log("** Simulation Delay - " + (Main.simulationDelay < 0? "0" : "" + Main.simulationDelay));
		
		Logger.log("\n** Debug **");
	}
}
